// Copyright (c) 2015 David Muse
// See the COPYING file for more information.

#include <wikitext/private/dll.h>
#include <rudiments/compiler.h>

class WIKITEXT_DLLSPEC image_macrohandler : public compilerprocessor {
	public:
			image_macrohandler();
		bool	process(xmldomnode *tree,
				xmldomnode *metadata);
	private:
		xmldomnode	*handleMacro(xmldomnode *macro);
};

image_macrohandler::image_macrohandler() {
}

bool image_macrohandler::process(xmldomnode *tree, xmldomnode *metadata) {

	xmldomnode *child=tree->getFirstTagChild();
	while (!child->isNullNode()) {

		// get next in case we rebuild the tree a bit
		xmldomnode	*next=child->getNextTagSibling();

		// get the node name
		const char	*nodename=child->getName();

		// if it's an image macro then handle it...
		if (!charstring::compare(nodename,"macro") &&
			!charstring::compareIgnoringCase(
				child->getFirstTagChild("macro_name")->
					getAttributeValue("value"),"Image")) {
			child=handleMacro(child);
			if (child->isNullNode()) {
				return false;
			}
			continue;
		}

		// descend
		if (!process(child,metadata)) {
			return false;
		}

		// move on
		child=next;
	}

	return true;
}

xmldomnode *image_macrohandler::handleMacro(xmldomnode *macro) {

	// split args on comma
	char		**args;
	uint64_t	argcount;
	charstring::split(macro->getFirstTagChild("macro_args")->
					getAttributeValue("value"),
					",",false,&args,&argcount);

	// parse args...
	//
	// possible args:
	// * right, left, center, top, bottom, middle
	// * link=... - a url to link to, or blank to omit a link
	// * nolink - omit the link
	// * key=value - css attribute/value
	const char	*src=(argcount>0)?args[0]:"";
	const char	*href=src;
	stringbuffer	style;
	for (uint64_t i=1; i<argcount; i++) {
		if (!charstring::compareIgnoringCase(args[i],"right") ||
			!charstring::compareIgnoringCase(args[i],"left")) {
			style.append("align: ");
			style.append(args[i]);
			style.append("; ");
		} else if (!charstring::compareIgnoringCase(args[i],"center") ||
			!charstring::compareIgnoringCase(args[i],"top") ||
			!charstring::compareIgnoringCase(args[i],"bottom") ||
			!charstring::compareIgnoringCase(args[i],"middle")) {
			style.append("valign: ");
			style.append(args[i]);
			style.append("; ");
		} else if (!charstring::compareIgnoringCase(
						args[i],"link=",5)) {
			href=args[i]+5;
		} else if (!charstring::compareIgnoringCase(
						args[i],"nolink")) {
			href=NULL;
		} else {
			const char	*equals=
					charstring::findFirst(args[i],"=");
			if (equals) {
				style.append(args[i],(equals-args[i]));
				style.append(": ");
				style.append(equals+1);
				style.append("; ");
			} else {
				style.append(args[i]);
				style.append("; ");
			}
		}
	}

	// add link/image
	xmldomnode	*retval=NULL;
	xmldomnode	*img=NULL;
	if (!charstring::isNullOrEmpty(href)) {
		retval=macro->getParent()->
				insertTag("wt","e_link",macro->getPosition());
		retval->appendTag("wt","url")->setAttributeValue("value",href);
		if (!charstring::isNullOrEmpty(src)) {
			img=retval->appendTag("wt","img");
			img->appendTag("wt","txt")->
				setAttributeValue("value",src);
		}
	} else {
		img=macro->getParent()->
				insertTag("wt","img",macro->getPosition());
		img->appendTag("wt","txt")->setAttributeValue("value",src);
		retval=img;
	}

	// remove macro
	macro->getParent()->deleteChild(macro);

	// add style
	if (style.getStringLength()) {
		img->setAttributeValue("style",style.getString());
	}

	// clean up
	for (uint64_t ci=0; ci<argcount; ci++) {
		delete[] args[ci];
	}
	delete[] args;

	return retval;
}

extern "C" {
	WIKITEXT_DLLSPEC compilerprocessor *new_image() {
		return new image_macrohandler();
	}
}
